﻿using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System;
using System.Text;
using System.Threading.Tasks;

namespace ManageModel.Webapi.Middlewares
{
    /// <summary>
    /// http全局错误处理 使用方式 app.UseMiddleware HttpResponseExceptionMiddleware ();
    /// </summary>
    #region snippet_HttpResponseExceptionFilter
    public class HttpResponseExceptionMiddleware
    {
        private readonly RequestDelegate next;
        private readonly ILogger<HttpResponseExceptionMiddleware> logger;
        /// <summary>
        /// 构造
        /// </summary>
        /// <param name="next"></param>
        public HttpResponseExceptionMiddleware(RequestDelegate next, ILogger<HttpResponseExceptionMiddleware> logger)
        {
            this.next = next;
            this.logger = logger;
        }
        /// <summary>
        /// 执行
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public async Task InvokeAsync(HttpContext context)
        {
            try
            {
                await next.Invoke(context);
            }
            catch (Exception ex)
            {
                context.Response.ContentType = "application/problem+json";
                StringBuilder stringBuilder = new StringBuilder();
                stringBuilder.AppendLine(ex.Message);
                logger.LogError(ex, "异常信息：{0}", ex.Message);
                var stream = context.Response.Body;
                await System.Text.Json.JsonSerializer.SerializeAsync(stream, new { code = "0", message = stringBuilder.ToString() });
            }
        }
        /// <summary>
        /// Exceptions the handler.自定义异常处理方法 app.UseExceptionHandler(builder => builder.Use(ExceptionHandlerDemo));
        /// </summary>
        /// <param name="httpContext">The HTTP context.</param>
        /// <param name="next">The next.</param>
        public static async Task ExceptionHandler(HttpContext httpContext, Func<Task> next)
        {
            //该信息由ExceptionHandlerMiddleware中间件提供，里面包含了ExceptionHandlerMiddleware中间件捕获到的异常信息。
            var exceptionDetails = httpContext.Features.Get<IExceptionHandlerFeature>();
            var ex = exceptionDetails?.Error;

            if (ex != null)
            {
                httpContext.Response.ContentType = "application/json";

                var title = "An error occured: " + ex.Message;
                var details = ex.ToString();

                var problem = new ProblemDetails
                {
                    Status = 500,
                    Title = title,
                    Detail = details
                };

                var stream = httpContext.Response.Body;
                await System.Text.Json.JsonSerializer.SerializeAsync(stream, problem);
            }
        }
    }
    #endregion
}
